#pragma once

#include <iostream>
#include <string>
#include "Connection.hpp"
#include "PackpageParse.hpp"

class HandleConnection
{
    static const int bufferSize = 4096;//定义的缓冲区块的大小
public:
    HandleConnection(handle_t parse) : _parse(parse)
    {}
    ~HandleConnection()
    {}
    void HandleRecv(Connection *con)
    {
        errno = 0;
        // 保证读取完整，循环只提供一个出口!
        while(true)
        {
            char buffer[bufferSize];
            ssize_t n = ::recv(con->SockFd(),buffer,sizeof(buffer)-1,0);
            if(n > 0) 
            {
                buffer[n] = 0;
                con->AppendRecvBuffer(buffer);
            }
            else
            {
               if(errno == EWOULDBLOCK)
                {
                    //表示数据被读取完成
                    break;
                }
                else if(errno == EINTR)//调用函数的过程被信号中断
                {
                    continue;
                }
                else 
                {
                    con->_error_handle(con);
                    return;
                }
            }
        }
        // 交给上层解析报文
        _parse(con);
        
    }
    void HandleSend(Connection *con)
    {
        errno = 0;
        while(true)
        {
            ssize_t n = ::send(con->SockFd(),con->SendBuffer().c_str(),con->SendBuffer().size(),0);
            if(n > 0)
            {
                con->ClearBuffer(n);
                if(con->SendBuffer().empty()) break;
            }
            else if(n == 0)
            {
                return;
            }
            else 
            {
                if(errno == EWOULDBLOCK)
                {
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else
                {
                    con->_error_handle(con);
                    return;
                }
            }
        }
        //发送条件不满足，设置写事件关心！
        if(!con->SendBuffer().empty())
        {
            con->_R->EnableConnectionReadWrite(con->SockFd(),true,true);
        }
        else
        {
            con->_R->EnableConnectionReadWrite(con->SockFd(),true,false);
        }
    }
    void HandleError(Connection *con)
    {
        //异常处理
        //1.先移除内核的fd
        //2.移除Reactor中的fd
        //3.关闭fd
        con->_R->DeleteConnection(con);
    }

private:
    handle_t _parse;
};